package jco3.core;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sap.conn.jco.JCoField;
import com.sap.conn.jco.JCoFieldIterator;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoMetaData;
import com.sap.conn.jco.JCoParameterField;
import com.sap.conn.jco.JCoParameterList;
import com.sap.conn.jco.JCoRecord;
import com.sap.conn.jco.JCoStructure;
import com.sap.conn.jco.JCoTable;

import freemarker.template.Configuration;

public class RfcUtils {
	/**
	 * JCo中，与表参数相关的两个接口是JCoTable和JCoRecordMetaDta(表头), 
	 * JCoTable就是RFC中table参数。
	 * 对JCoTable，输出表头和行项目。表头通过获取JCoTable的meta-data，然后使用meta-data的getName()方法。
	 * JCoRecordMetaData tableMeta = jcoTable.getRecordMetaData();  
	 * ....... 
	 * JCoTable每一行都是一个JCoStructure，可以通过setRow()设置指针的位置，然后再遍历各个field：
	 */
	
	private static final Configuration fmConfig = new Configuration();
	
	public static void main(String[] args) {
		getConfigs();
	}
	
	public static List<String> getConfigs(){
		List configs = new ArrayList<>();
		File dir = new File("../appconfig/sap/");
		File[] fs = dir.listFiles();
		if(fs == null) return configs;
		for(int i=0;i<fs.length;i++) {
			File file = fs[i];
			if(!fs[i].isDirectory()) {
				String filename = file.getName();
				if((!filename.startsWith("test-")) && (filename.endsWith(".properties"))) {
					configs.add(filename.substring(0,filename.length() - ".properties".length()));
				}
			}
		}
		return configs;
	}
	
	public static JSONObject jcoFunctionMeta2Json(JCoFunction jcoFunction) {
		JSONObject jsonRoot = new JSONObject(true);
		try {
			JCoParameterList input = jcoFunction.getImportParameterList();
			JCoParameterList output = jcoFunction.getExportParameterList();
			JCoParameterList tableList = jcoFunction.getTableParameterList();
			
			jsonRoot.put("Name",jcoFunction.getName());
			
			if(input !=null) {
				JSONObject jsonObject = jcoRecordMeta2Json(input);
				jsonRoot.put("ImportParameterList", jsonObject);
			}else {
				JSONObject jsonObject = new JSONObject();
				jsonRoot.put("ImportParameterList", jsonObject);
			}
			
			if(output != null) {
				JSONObject jsonObject = jcoRecordMeta2Json(output);
		        jsonRoot.put("ExportParameterList", jsonObject);
			}else {
				JSONObject jsonObject = new JSONObject();
		        jsonRoot.put("ExportParameterList", jsonObject);
			}
			
			if (tableList != null) {
				JSONObject jsonObject = jcoRecordMeta2Json(tableList);
				jsonRoot.put("TableParameterList", jsonObject);
			} else {
				JSONObject jsonObject = new JSONObject();
				jsonRoot.put("TableParameterList", jsonObject);
			}
		} catch (Exception e) {
		}
		return jsonRoot;
	}
	
	public static JSONObject jcoRecordMeta2Json(JCoRecord jcoRecord) {
		JSONObject jsonRoot = new JSONObject(true);
		try {
			JCoMetaData jcoMetaData = jcoRecord.getMetaData();
			jsonRoot.put("Name", jcoMetaData.getName());
			
			JCoFieldIterator iterator = jcoRecord.getFieldIterator();
			List list = new ArrayList<>(jcoMetaData.getFieldCount());
			while(iterator.hasNextField()) {
				JCoField field = iterator.nextField();
				
				JSONObject jsonField = new JSONObject(true);
				jsonField.put("Name", field.getName());
				jsonField.put("Type", field.getTypeAsString());
				jsonField.put("ClassName", jcoMetaData.getClassNameOfField(field.getName()));
				
				if (jcoMetaData.isStructure(field.getName())) {
			          jsonField.put("Length", Integer.valueOf(jcoMetaData.getRecordMetaData(field.getName()).getRecordLength()));
			          jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
			          jsonField.put(field.getTypeAsString(), jcoStructureMeta2Json(field.getStructure()));
		        } else if (jcoMetaData.isTable(field.getName())) {
		          jsonField.put("Length", Integer.valueOf(jcoMetaData.getRecordMetaData(field.getName()).getRecordLength()));
		          jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		          jsonField.put(field.getTypeAsString(), jcoTableMeta2Json(field.getTable()));
		        } else {
		          jsonField.put("Length", Integer.valueOf(jcoMetaData.getLength(field.getName())));
		          jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		          jsonField.put("Value", "");
		        }
		        list.add(jsonField);
			}
			jsonRoot.put("Fields", new JSONArray(list));
		} catch (Exception e) {
		}
		return jsonRoot;
	}
	
	public static JSONObject jcoStructureMeta2Json(JCoStructure jCoStructure) {
		JSONObject jsonRoot = new JSONObject(true);
		try {
			JCoMetaData jcoMetaData = jCoStructure.getMetaData();
			jsonRoot.put("Name", jcoMetaData.getName());
			
			JCoFieldIterator iterator = jCoStructure.getFieldIterator();
			List list = new ArrayList<>(jcoMetaData.getFieldCount());
			while(iterator.hasNextField()) {
				JCoField field = iterator.nextField();

		        JSONObject jsonField = new JSONObject(true);
		        jsonField.put("Name", field.getName());
		        jsonField.put("Type", field.getTypeAsString());
		        jsonField.put("ClassName", jcoMetaData.getClassNameOfField(field.getName()));

		        if (jcoMetaData.isStructure(field.getName())) {
		          jsonField.put("Length", Integer.valueOf(jcoMetaData.getRecordMetaData(field.getName()).getRecordLength()));
		          jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		          jsonField.put(field.getTypeAsString(), jcoStructureMeta2Json(field.getStructure()));
		        } else if (jcoMetaData.isTable(field.getName())) {
		          jsonField.put("Length", Integer.valueOf(jcoMetaData.getRecordMetaData(field.getName()).getRecordLength()));
		          jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		          jsonField.put(field.getTypeAsString(), jcoTableMeta2Json(field.getTable()));
		        } else {
		          jsonField.put("Length", Integer.valueOf(jcoMetaData.getLength(field.getName())));
		          jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		          jsonField.put("Value", "");
		        }
		        list.add(jsonField);
			}
			jsonRoot.put("Fields", new JSONArray(list));
		} catch (Exception e) {
		}
		return jsonRoot;
	}
	
	public static JSONObject jcoTableMeta2Json(JCoTable jcoTable) {
		JSONObject jsonRoot = new JSONObject(true);
		
		try {
			JCoMetaData jcoMetaData = jcoTable.getMetaData();
			jsonRoot.put("Name", jcoMetaData.getName());
			
			JCoFieldIterator iterator = jcoTable.getFieldIterator();
			List list = new ArrayList<>(jcoMetaData.getFieldCount());
			while(iterator.hasNextField()) {
				JCoField field = iterator.nextField();
				
				JSONObject jsonField = new JSONObject(true);
				jsonField.put("Name", field.getName());
		        jsonField.put("Type", field.getTypeAsString());
		        jsonField.put("ClassName", jcoMetaData.getClassNameOfField(field.getName()));
		        
		        if (jcoMetaData.isStructure(field.getName())) {
		        	jsonField.put("Length", Integer.valueOf(jcoMetaData.getRecordMetaData(field.getName()).getRecordLength()));
		            jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		            jsonField.put(field.getTypeAsString(), jcoStructureMeta2Json(field.getStructure()));
		        }else if(jcoMetaData.isTable(field.getName())) {
		        	jsonField.put("Length", Integer.valueOf(jcoMetaData.getRecordMetaData(field.getName()).getRecordLength()));
		            jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		            jsonField.put(field.getTypeAsString(), jcoTableMeta2Json(field.getTable()));
		        }else {
		            jsonField.put("Length", Integer.valueOf(jcoMetaData.getLength(field.getName())));
		            jsonField.put("Description", field.getDescription() == null ? "" : field.getDescription());
		            jsonField.put("Value", "");
		        }
		        list.add(jsonField);
			}
			jsonRoot.put("Fields", new JSONArray(list));
		} catch (Exception e) {
		}
		return jsonRoot;
	}
	
}